﻿using System.Threading;

namespace TestingConcurrencyBenchmark.Helpers
{
    /// <summary>
    /// An adapter for built in semaphores to make sure the signatures remain consistant between benchmarks
    /// in different languages
    /// </summary>
    public class BenchmarkSemaphore
    {
        /// <summary>
        /// The semaphore to "adapt"
        /// </summary>
        private readonly Semaphore _semaphore;

        /// <summary>
        /// Creates a new adapter based on Dijkstra's definition: A semaphore is initialised with a certain count
        /// and is infinitely large. In this case "infinite" is faked by using int.MaxValue
        /// </summary>
        /// <param name="initialCount">The count this semaphore should start with</param>
        public BenchmarkSemaphore(int initialCount)
        {
            _semaphore = new Semaphore(initialCount, int.MaxValue);
        }

        /// <summary>
        /// "Releases the semaphore", equivalent to calling "V" (verhoog) in Dijkstra's definition
        /// </summary>
        public void Release()
        {
            _semaphore.Release();
        }

        /// <summary>
        /// "Releases the semaphore" with a certain amount, equivalent to calling "V" (verhoog) of Dijkstra's definition
        /// an amount of times consistent with the given count
        /// </summary>
        /// <param name="count"></param>
        public void Release(int count)
        {
            _semaphore.Release(count);
        }

        /// <summary>
        /// "Wait on this semaphore" if the internal count of the semaphore equivals zero. Equivalent to calling "P" (prolaag)
        /// of Dijkstra's definition
        /// </summary>
        public void WaitOne()
        {
            _semaphore.WaitOne();
        }
    }
}
